Passed
Push — master ( 501c3e...cc7abf )
by Night
01:09
created

stringFuncs.firstLetterLower   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
/** global: UB */
2
3
// CASING
4
5
// PROVIDES THE TABLES USED FOR FAST CASE-INSENSITIVE STRING COMPARISON
6
// FOR THESE TABLES SEE "unicode uppercase lowercase tables.xlsx"
7
8
// meta tables
9
UB.UTF_casingRangedLowerS = [97, 224, 1072, 1121, 1169, 1377, 4304, 7681, 7841, 9424];
10
UB.UTF_casingRangedLowerE = [122, 246, 1103, 1153, 1215, 1414, 4341, 7829, 7929, 9449];
11
UB.UTF_casingRangedIncrement = [1, 1, 1, 2, 2, 1, 1, 2, 2, 1];
12
UB.UTF_casingRangedUpper = [65, 192, 1040, 1120, 1168, 1329, 4256, 7680, 7840, 9398];
13
14
// raw tables
15
UB.UTF_casingRawLower = [248, 249, 250, 251, 252, 253, 254, 255, 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293, 295, 297, 299, 301, 303, 305, 307, 309, 311, 314, 316, 318, 320, 322, 324, 326, 328, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, 353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 378, 380, 382, 387, 389, 392, 396, 402, 409, 417, 419, 421, 424, 429, 432, 436, 438, 441, 445, 454, 457, 460, 462, 464, 466, 468, 470, 472, 474, 476, 479, 481, 483, 485, 487, 489, 491, 493, 495, 499, 501, 507, 509, 511, 513, 515, 517, 519, 521, 523, 525, 527, 529, 531, 533, 535, 595, 596, 599, 600, 601, 603, 608, 611, 616, 617, 623, 626, 629, 643, 648, 650, 651, 658, 940, 941, 942, 943, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 995, 997, 999, 1001, 1003, 1005, 1007, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1118, 1119, 1218, 1220, 1224, 1228, 1233, 1235, 1237, 1239, 1241, 1243, 1245, 1247, 1249, 1251, 1253, 1255, 1257, 1259, 1263, 1265, 1267, 1269, 1273, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 7952, 7953, 7954, 7955, 7956, 7957, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 7984, 7985, 7986, 7987, 7988, 7989, 7990, 7991, 8000, 8001, 8002, 8003, 8004, 8005, 8017, 8019, 8021, 8023, 8032, 8033, 8034, 8035, 8036, 8037, 8038, 8039, 8064, 8065, 8066, 8067, 8068, 8069, 8070, 8071, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103, 8112, 8113, 8144, 8145, 8160, 8161];
16
UB.UTF_casingRawUpper = [216, 217, 218, 219, 220, 221, 222, 376, 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, 286, 288, 290, 292, 294, 296, 298, 300, 302, 73, 306, 308, 310, 313, 315, 317, 319, 321, 323, 325, 327, 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 350, 352, 354, 356, 358, 360, 362, 364, 366, 368, 370, 372, 374, 377, 379, 381, 386, 388, 391, 395, 401, 408, 416, 418, 420, 423, 428, 431, 435, 437, 440, 444, 452, 455, 458, 461, 463, 465, 467, 469, 471, 473, 475, 478, 480, 482, 484, 486, 488, 490, 492, 494, 497, 500, 506, 508, 510, 512, 514, 516, 518, 520, 522, 524, 526, 528, 530, 532, 534, 385, 390, 394, 398, 399, 400, 403, 404, 407, 406, 412, 413, 415, 425, 430, 433, 434, 439, 902, 904, 905, 906, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 908, 910, 911, 994, 996, 998, 1000, 1002, 1004, 1006, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1038, 1039, 1217, 1219, 1223, 1227, 1232, 1234, 1236, 1238, 1240, 1242, 1244, 1246, 1248, 1250, 1252, 1254, 1256, 1258, 1262, 1264, 1266, 1268, 1272, 7944, 7945, 7946, 7947, 7948, 7949, 7950, 7951, 7960, 7961, 7962, 7963, 7964, 7965, 7976, 7977, 7978, 7979, 7980, 7981, 7982, 7983, 7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999, 8008, 8009, 8010, 8011, 8012, 8013, 8025, 8027, 8029, 8031, 8040, 8041, 8042, 8043, 8044, 8045, 8046, 8047, 8072, 8073, 8074, 8075, 8076, 8077, 8078, 8079, 8088, 8089, 8090, 8091, 8092, 8093, 8094, 8095, 8104, 8105, 8106, 8107, 8108, 8109, 8110, 8111, 8120, 8121, 8152, 8153, 8168, 8169];
17
18
19
// final tables (= ranged + raw)
20
UB.UTF_casingTablesMax = 9450;
21
22
UB.initCasing = function(){
23
	
24
	// exit if already initialized
25
	if (UB.UTF_lowerToUpper != null){
1 ignored issue
show
Best Practice introduced by
Comparing UB.UTF_lowerToUpper to null using the != operator is not safe. Consider using !== instead.
Loading history...
26
		return;
27
	}
28
	
29
	// CALC CASING CONVERSION TABLES
30
	UB.UTF_lowerToUpper = [];
31
	UB.UTF_upperToLower = [];
32
	
33
	// init by mapping to self (most chars dont have an uppercase/lowercase version)
34
	for (var n = 0, nlast = UB.UTF_casingTablesMax;n <= nlast;n++){
35
		UB.UTF_lowerToUpper[n] = n;
36
		UB.UTF_upperToLower[n] = n;
37
	}
38
	
39
	// per range
40
	for (var r = 0, rl = UB.UTF_casingRangedLowerS.length;r<rl;r++){
41
		
42
		// per value in range
43
		var inc = UB.UTF_casingRangedIncrement[r];
44
		var offset = UB.UTF_casingRangedUpper[r] - UB.UTF_casingRangedLowerS[r];
45
		for (var lower = UB.UTF_casingRangedLowerS[r], lowerlast = UB.UTF_casingRangedLowerE[r];lower <= lowerlast;lower += inc){
46
			
47
			// calc uppercase
48
			var upper = lower + offset;
49
			
50
			// store in table
51
			UB.UTF_lowerToUpper[lower] = upper;
52
			UB.UTF_upperToLower[upper] = lower;
53
			
54
		}
55
		
56
	}
57
	
58
	// per raw value
59
	for (var n = 0, nl = UB.UTF_casingRawLower.length;n<nl;n++){
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable n already seems to be declared on line 34. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
60
		
61
		lower = UB.UTF_casingRawLower[n];
62
		upper = UB.UTF_casingRawUpper[n];
63
		
64
		// store in table
65
		UB.UTF_lowerToUpper[lower] = upper;
66
		UB.UTF_upperToLower[upper] = lower;
67
		
68
	}
69
	
70
	// fix bug in unicode table .. "I" >> "i"
71
	UB.UTF_upperToLower[73] = 105;
72
	
73
	
74
}
75
76
77
var arrayFuncs = {
78
79
	camelCaseMergeWords: function(firstCharCaps = false){
80
		var words = this;
81
		
82
		// lowercase first letter
83
		words[0] = firstCharCaps ? words[0].firstLetterUpper() : words[0].firstLetterLower();
84
		
85
		// loop thru all words
86
		var newWords = "";
87
		for (var w = 0, wl = words.length;w<wl;w++){
88
			var word = words[w].replace(UB.regex.Trim, '');
89
			
90
			// cap first letter if not 1st word
91
			newWords += w == 0 ? word : word.firstLetterUpper();
1 ignored issue
show
Best Practice introduced by
Comparing w to 0 using the == operator is not safe. Consider using === instead.
Loading history...
92
		}
93
		return newWords;
94
	},
95
	
96
	none:null
97
};
98
99
// register funcs
100
UB.registerFuncs(Array.prototype, arrayFuncs);
101
102
103
var stringFuncs = {
104
	
105
	// casing
106
	camelCaseSeperate: function(){
107
		var camelCase = this;
108
		
109
		// loop thru all chars
110
		var lastUp = false;
111
		var lastSpace = false;
112
		var newName = [];
113
		var len = 0;
114
		for (var c = 0, cl = camelCase.length - 1;c <= cl;c++){
115
			var char = camelCase.charAt(c);
116
			var charNext = c < cl ? camelCase.charAt(c + 1) : "_";
117
			
118
			// if its a Capital ... and if prev is not also a capital ... or if the next is small
119
			var up = (char.toUpperCase() == char);
120
			var nextUp = (charNext.toUpperCase() == charNext);
121
			if ((up && (!lastUp || !nextUp) && !lastSpace) || char == "_") {
122
				
123
				// add a space
124
				if (len > 0 && newName[len - 1] != " "){
125
					newName.push(" ");
126
					len++;
127
				}
128
			}
129
			lastUp = up;
130
			
131
			// add the char
132
			if (char != "_"){
133
				newName.push(char);
134
				len++;
135
			}
136
			lastSpace = char == " ";
137
		}
138
		
139
		// caps first letter
140
		return newName.join("").firstLetterUpper();
141
	},
142
	camelCaseSeperateWords: function(){
143
		var camelCase = this;
144
		return camelCase.camelCaseSeperate().split(" ");
145
	},
146
	camelCaseMerge: function(firstCharCaps = false){
147
		var sentence = this;
148
		
149
		// exit quickly if no spaces .. no words to merge
150
		if (sentence.indexOf(" ") == -1) {
151
			if (firstCharCaps) {
152
				return sentence.firstLetterUpper();
153
			}else{
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
154
				return sentence;
155
			}
156
		}
157
		
158
		// merge words using camel case
159
		return sentence.split(" ").camelCaseMergeWords(firstCharCaps);
160
	},
161
	firstLetterUpper: function(){
162
		var str = this;
163
		str = str.trim();
164
		return str.charAt(0).toUpperCase() + str.substr(1);
165
	},
166
	firstLetterLower: function(){
167
		var str = this;
168
		str = str.trim();
169
		return str.charAt(0).toLowerCase() + str.substr(1);
170
	},
171
	toSmartCase: function(){
172
		var word = this;
173
		// home loan > Home Loan
174
		// PRNQ loan > PRNQ Loan
175
		return word.toCustomCase(";,. -_" + "\t" + "\n", true);
176
	},
177
	toSentenceCase: function(){
178
		var word = this;
179
		return word.toCustomCase(".", false);
180
	},
181
	toCustomCase: function(capsAfterChars, preserveCaps = false){
182
		var word = this;
183
		var nextCaps = true;// first char caps
184
		
185
		// per char
186
		var chars = word.splitChars();
187
		var chars2 = [];
188
		for (var c = 0, cl = chars.length;c<cl;c++){
189
			var ch = chars[c];
190
			var added = false;
191
			
192
			// add as CAPS if wanted
193
			if (nextCaps) {
194
				nextCaps = false;
195
				chars2.push(ch.toUpperCase());
196
				added = true;
197
			}
198
			
199
			// next char should have caps
200
			if (capsAfterChars.indexOf(ch) > -1) {
201
				nextCaps = true;
202
			}
203
			
204
			// add normally
205
			if (!added) {
206
				
207
				// preserve caps if wanted
208
				if (preserveCaps && ch.toUpperCase() == ch) {
209
					chars2.push(ch);
210
				}else {
211
					
212
					// add as lower case
213
					chars2.push(ch.toLowerCase());
214
				}
215
			}
216
		}
217
		return chars2.join("");
218
	},
219
	toTitleCase: function(){
220
		var word = this;
221
		// home loan > Home Loan
222
		// PRNQ loan > Prnq Loan
223
		return word.toCustomCase(";,. -_" + "\t" + "\n", false);
224
	},
225
	toSentenceTitleCase: function(){
226
		var title = this;
227
		var parts = [];
228
		var index = 0;
229
		
230
		// create regexps
231
		var small = "(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v[.]?|via|vs[.]?)";
232
		var punct = "([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]*)";
233
		var r1 =  new RegExp("\\b([A-Za-z][a-z.'Õ]*)\\b", "g");
234
		var r2 =  new RegExp("[A-Za-z]\\.[A-Za-z]", "");
235
		var r3 =  new RegExp("\\b" + small + "\\b", "ig");
236
		var r4 =  new RegExp("^" + punct + small + "\\b", "ig");
237
		var r5 =  new RegExp("\\b" + small + punct + "$", "ig");
238
		var r6 =  new RegExp(" V(s?)\\. ", "ig");
239
		var r7 =  new RegExp("(['Õ])S\\b", "ig");
240
		var split =  new RegExp("[:.;?!] |(?: |^)[\"Ò]", "g");
241
		
242
		// per word in string
243
		while (true) {
244
			var m = split.exec(title);
245
			
246
			var ToLowerCase = function(x){
247
				return x.toLowerCase();
248
			}
249
			var ToUpperCaseFirst = function(x){
250
				return x.firstLetterUpper();
251
			}
252
253
			// smart capatalize
254
			parts.push( title.substring(index, m ? m.index : title.length).replace(r1, function(all) {
255
				return r2.test(all) ? all : all.firstLetterUpper();
256
			}).replace(r3, ToLowerCase).replace(r4, function (all, punct, word){
257
				return punct + word.firstLetterUpper();
258
			}).replace(r5, ToUpperCaseFirst));
259
			
260
			index = split.lastIndex;
261
			
262
			if ( m ) parts.push( m[0] );
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
263
			else break;
264
		}
265
		
266
		return parts.join("").replace(r6, " v$1. ").replace(r7, "$1s");
267
	},
268
	toCamelCase: function(){
269
		var word = this;
270
		return word.camelCaseMerge(false);
271
	},
272
	toPascalCase: function(){
273
		var word = this;
274
		return word.camelCaseMerge(true);
275
	},
276
	toURLCase: function(){
277
		var path = this;
278
		path = path.removeAll("&");
279
		path = path.removeAll("\"");
280
		path = path.removeAll("'");
281
		path = path.removeAll(",");
282
		path = path.removeAll("?");
283
		path = path.setSlash("/").replaceAll(" ", "-");	
284
		path = path.replaceAll("----", "-");
285
		path = path.replaceAll("---", "-");
286
		path = path.replaceAll("--", "-");
287
		return path.toLowerCase();
288
	},
289
	pascalToCamelCase: function(){
290
		var word = this;
291
		
292
		// no change if already begins with lowercase letter
293
		if (word.substr(0, 1).isLowercase()) {
294
			return word;
295
		}
296
		
297
		// make the first word lowercase
298
		
299
		// if >2 chars are uppercase
300
		var num = word.countStartingUppercase();
301
		if (num > 2) {	
302
			
303
			// lowercase all uppercase chars (except the last)
304
			return word.firstXCharsLower(num - 1);
305
		}
306
		
307
		// lowercase first char only
308
		return word.firstLetterLower();
309
	},
310
	firstXCharsUpper: function(numOfChars){
311
		var text = this;
312
		return text.setRange(0, numOfChars - 1, text.getRange(0, numOfChars - 1).toUpperCase());
313
	},
314
	firstXCharsLower: function(numOfChars){
315
		var text = this;
316
		return text.setRange(0, numOfChars - 1, text.getRange(0, numOfChars - 1).toLowerCase());
317
	},
318
	none:null
319
};
320
321
// register funcs
322
UB.registerFuncs(String.prototype, stringFuncs);